package com.hmdp.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hmdp.dto.LoginFormDTO;
import com.hmdp.dto.Result;
import com.hmdp.dto.UserDTO;
import com.hmdp.entity.User;
import com.hmdp.entity.UserInfo;
import com.hmdp.service.IUserInfoService;
import com.hmdp.service.IUserService;
import com.hmdp.utils.RedisConstants;
import com.hmdp.utils.RegexUtils;
import com.hmdp.utils.UserHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author 虎哥
 * @since 2021-12-22
 */
@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {

    @Resource(name = "userService")
    private IUserService userService;

    @Resource(name = "userInfoService")
    private IUserInfoService userInfoService;

    @Resource
    StringRedisTemplate stringRedisTemplate;


    /**
     * 发送手机验证码
     */
    @PostMapping("code")
    public Result sendCode(@RequestParam("phone") String phone, HttpSession session) {
        return userService.sendMsg(phone,session);
    }

    /**
     * 登录功能
     * @param loginForm 登录参数，包含手机号、验证码；或者手机号、密码
     */
    @PostMapping("/login")
    public Result login(@RequestBody LoginFormDTO loginForm, HttpSession session){
        //1、验证当前是否是验证码登录方式
        if(!StringUtils.isEmpty(loginForm.getCode())){

            String phone = loginForm.getPhone();

            if(RegexUtils.isPhoneInvalid(phone)){
                return Result.fail("电话格式不正确");
            }
            //2、如果session都没有，则没发送验证码
//            if(session==null){
//                Result.fail("请发送验证码进行验证");
//            }

            //3、取出验证码
//            String code = (String) session.getAttribute("tel:code" + loginForm.getPhone());

            //4、如果有session，但是拿不到code，说明发送验证码的手机号与当前提交的手机号不一样
//            if(StringUtils.isEmpty(code)){
//                Result.fail("当前手机号暂未发送验证码");
//            }

            //从redis中拿验证码
            ValueOperations<String, String> stringStringValueOperations = stringRedisTemplate.opsForValue();
            String code = stringStringValueOperations.get(RedisConstants.LOGIN_CODE_KEY + loginForm.getPhone());
            //验证码失效
            if(StringUtils.isEmpty(code)){
                Result.fail("验证码失效");
            }

            //5、验证失败
            if(!code.equals(loginForm.getCode())){
                Result.fail("验证码错误");
            }

            LambdaQueryWrapper<User> userLambdaQueryWrapper = new LambdaQueryWrapper<User>();
            userLambdaQueryWrapper.eq(!StringUtils.isEmpty(loginForm.getPhone()),User::getPhone,loginForm.getPhone());
            User user = userService.getOne(userLambdaQueryWrapper);
            //6、当前用户未注册
            if(user==null){
                user = userService.createUserWithPhone(loginForm.getPhone());
            }

            UserDTO userDTO = new UserDTO();
            BeanUtils.copyProperties(user,userDTO);
//            session.setAttribute("user",userDTO);
            //这里不存session中，而是存进redis
            //获取hash操作对象
            HashOperations<String, String, String> stringObjectObjectHashOperations = stringRedisTemplate.opsForHash();

            //弄一个hashmap存属性
            HashMap<String, String> objectObjectHashMap = new HashMap<>();

            //这里有封装了一个UserDTOConstants,获取属性名称
            objectObjectHashMap.put(UserDTO.UserDTOConstants.USER_ID,String.valueOf(userDTO.getId()));
            objectObjectHashMap.put(UserDTO.UserDTOConstants.USER_NICK_NAME,userDTO.getNickName());
            objectObjectHashMap.put(UserDTO.UserDTOConstants.ICON, userDTO.getIcon());

            //生成UUID
            String token = UUID.randomUUID().toString();

            //存进redis
            stringObjectObjectHashOperations.putAll(RedisConstants.LOGIN_USER_KEY+token,objectObjectHashMap);

            //设置超时时间
            stringRedisTemplate.expire(RedisConstants.LOGIN_USER_KEY+token,30, TimeUnit.MINUTES);

            //删除验证码
            stringRedisTemplate.delete(RedisConstants.LOGIN_CODE_KEY+phone);


            return Result.ok(token);
        }
        return Result.fail("密码登录功能未完成");
    }

    /**
     * 登出功能
     * @return 无
     */
    @PostMapping("/logout")
    public Result logout(){
        // TODO 实现登出功能
        return Result.fail("功能未完成");
    }

    @GetMapping("me")
    public Result me(){
        UserDTO user = UserHolder.getUser();
        return Result.ok(user);
    }

    @GetMapping("/info/{id}")
    public Result info(@PathVariable("id") Long userId){
        // 查询详情
        UserInfo info = userInfoService.getById(userId);
        if (info == null) {
            // 没有详情，应该是第一次查看详情
            return Result.ok();
        }
        info.setCreateTime(null);
        info.setUpdateTime(null);
        // 返回
        return Result.ok(info);
    }
}
